#ifndef __STATISTICS_H__
#define __STATISTICS_H__

#include "base/Bucket.h"
#include "base/Counter.h"
#include "base/SpeculativeCounter.h"
#include "util/Histogram.h"
#include "util/Pool.h"
#include "util/Vector.h"

class Processor;

class StatisticsCollection {
    
 public:
    NEW_DELETE_OPERATORS_H(StatisticsCollection,NoSuper);
    StatisticsCollection (const char* collectionName, bool rollback = false);
    virtual ~StatisticsCollection ();

    void setDefaultRollbackBucket (Bucket* b);
    
    Bucket*  addBucket (const char* outputName,
                        Bucket* rollbackRecipient = NULL);
    Bucket* addRollbackBucket (const char* outputName);
    Counter* addCounter (const char* outputName);
    SpeculativeCounter* addSpeculativeCounter (const char* outputName,
                                               const char* outputRollbackName);
    Histogram* addHistogram (const char* outputName, int size);

    virtual void rollback ();
    virtual void commit ();
    virtual void rollbackSpeculativeCounters ();
    virtual void commitSpeculativeCounters ();
    Vector<Bucket*>* getBuckets ();
    Bucket* getBucket (const char* name);
    Counter* getCounter (const char* name);
    void printStatisticsCollection (FILE* statFile, const char* prefix);
    uint64 getSpeculativeCountersSpeculativeSum ();

  private:
    char*                       collectionName;
    Vector<Bucket*>             buckets;
    Vector<Bucket*>             rollbackBuckets;
    Vector<Counter*>            counters;
    Vector<SpeculativeCounter*> speculativeCounters;
    Vector<Histogram*>          histograms;

    bool    rollbackEnabled;
    Bucket* rollbackBucket;
    
    //Debug info
    static uint globalCollectionID;
    uint        collectionID;
    
    void printBuckets             (FILE* statFile, const char* prefix);
    void printCounters            (FILE* statFile, const char* prefix);
    void printSpeculativeCounters (FILE* statFile, const char* prefix);
    void printHistograms          (FILE* statFile);
};

#endif
